﻿using System.ComponentModel;
using System.Reflection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using ZeroSum.Attributes;
using ZeroSum.Extend.EFCore.MySql.Attributes;
using ZeroSum.Extensions;
using ZeroSum.Helpers;
using ZeroSumZSA.Api.Apis;

namespace ZeroSumZSA.Api.Controllers;

/// <summary>
///     授权管理
/// </summary>
[Description("管理-授权管理")]
public class TestController : ApiController
{
    /// <summary>
    ///     测试
    /// </summary>
    [HttpPost]
    [AllowAnonymous]
    public Task DbTest()
    {
        var assemblies = new List<Assembly>();
        assemblies.AddRange(AssemblyHelper.GetProjectAssemblies());
        assemblies.AddRange(AssemblyHelper.GetPackageAssemblies(nameof(ZeroSum)));

        var modelBuilder = new ModelBuilder();
        // 扫描需要注册的实体类（通过实体标签）
        RegisterEntityByAttribute(assemblies, modelBuilder);
        return Task.CompletedTask;
    }

    /// <summary>
    ///     通过EntityAttribute来扫描多个程序集中需要注册的实体类
    /// </summary>
    /// <param name="assemblies"></param>
    /// <param name="builder"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void RegisterEntityByAttribute(IEnumerable<Assembly> assemblies, ModelBuilder builder)
    {
        foreach (var assembly in assemblies) RegisterEntityByAttribute(assembly, builder);
    }

    /// <summary>
    ///     通过EntityAttribute来扫描单个程序集中需要注册的实体类
    /// </summary>
    /// <param name="assembly"></param>
    /// <param name="builder"></param>
    private void RegisterEntityByAttribute(Assembly assembly, ModelBuilder builder)
    {
        var types = assembly.GetTypes().Where(t => t.HasAttribute<EntityAttribute>());
        foreach (var type in types)
        {
            var mode = builder.Entity(type);
            var propertyInfos = type.GetProperties()
                .Where(x => x.GetCustomAttribute<HasValueGeneratorAttribute>() != null);
            foreach (var propertyInfo in propertyInfos)
            {
                var hasValueGeneratorAttribute = propertyInfo.GetAttribute<HasValueGeneratorAttribute>();
                mode.Property(propertyInfo.PropertyType, propertyInfo.Name).ValueGeneratedOnAdd()
                    .HasValueGenerator(hasValueGeneratorAttribute?.ValueGeneratorType);
            }
        }
    }
}